﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Linq;
using System.Xml.Linq;
using DocumentFormat.OpenXml.Packaging;

namespace Songhay.OpenXml
{
    using Songhay.OpenXml.Models;
    using Transformations;

    /// <summary>
    /// Static members for Open XML.
    /// </summary>
    public static partial class OpenXmlUtility
    {
        /// <summary>
        /// Transforms the nodes in a Word document package.
        /// </summary>
        /// <param name="wordDoc">The Word doc.</param>
        /// <param name="settings">The settings.</param>
        /// <param name="node">The node.</param>
        /// <param name="imageHandler">The image handler.</param>
        /// <remarks>
        /// For more detail, see:
        ///     “Recursive Approach to Pure Functional Transformations of XML”
        ///     (http://blogs.msdn.com/b/ericwhite/archive/2009/07/20/a-tutorial-in-the-recursive-approach-to-pure-functional-transformations-of-xml.aspx)
        /// and
        ///     “Reducing Connaissance (Interconnectedness) and Increasing Robustness using LINQ”
        ///     (http://blogs.msdn.com/b/ericwhite/archive/2010/03/09/reducing-connaissance-interconnectedness-and-increasing-robustness-using-linq.aspx)
        /// by Eric White
        /// </remarks>
        public static object TransformPackageNode(WordprocessingDocument wordDoc,
            SonghayHtmlConverterSettings settings, XNode node,
            Func<ImageInfo, XElement> imageHandler)
        {
            var element = node as XElement;

            // Remove any nodes that have not been transformed:
            if(element == null) return null;

            object result = null;

            if((Transformations == null) || (Transformations.Count() < 1))
                throw new CompositionException(
                    "Too few transformations were imported. " +
                    "Review the MEF composition.");

            Transformations
                .Where(t => t.CanTransform(wordDoc, settings, node))
                .OrderBy(t => t.ExecutionOrdinal)
                .ToList().ForEach(t =>
                {
                    result = t.Transform(wordDoc, settings, node, imageHandler);
                });

            return result;
        }

        public static readonly
            IEnumerable<IWordProcessingDocumentTransformation>
                Transformations = new WordProcessingDocumentTransformations();
    }
}
